package com.yangcangclub.api.v1.system.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yangcangclub.commons.annotation.*;
import com.yangcangclub.commons.config.SysConfig;
import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.mail.MailEngine;
import com.yangcangclub.commons.mail.SimpleMailData;
import com.yangcangclub.commons.oss.OSSManageUtil;
import com.yangcangclub.commons.result.MessageEnum;
import com.yangcangclub.commons.result.ResultData;
import com.yangcangclub.commons.utils.*;
import com.yangcangclub.system.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 系统及配置
 */
@Controller
@RequestMapping("/yangcangclub/v1/system")
public class SystemController {
    private static Logger logger = LoggerFactory.getLogger(SystemController.class);
    @Autowired
    SystemService systemService;
    @Autowired
    SysConfig sysConfig;
    @Autowired
    OSSManageUtil oSSManageUtil;
    @Autowired
    MailEngine mailEngine;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    WechatJsSign wechatJsSign;


    /**
     * 获取图片验证码
     */
    @ResponseBody
    @RequestMapping(value = "/imgcode")
    public void imgcode (HttpServletResponse response, String key,String width,String height) {
        try {
            if(key==null||width==null||height==null){
                HttpServletUtil.WriteJSON(response, JSON.toJSONString(new ResultData(MessageEnum.PARMA_IS_EMPTY)));
            }else if( !StringUtil.isNumber(width)|| !StringUtil.isNumber(height)){
                HttpServletUtil.WriteJSON(response, JSON.toJSONString(new ResultData(MessageEnum.PARMA_FORMAT_ERROR)));
            }
            response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
            response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            systemService.getImgcode(response,key,Integer.valueOf(width),Integer.valueOf(height));//输出图片方法
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    @ResponseBody
    @RequestMapping(value = "/email")
    @ApolloSecurity(limit = 20,time = TimeEnum.MINUTE)
    public ResultData sendMail(String email) {
        ResultData  resultData ;
        try {

            String randomNum= StringUtil.getRandomNum(4);
            boolean isSuccess = mailEngine.sendRegisteMail(randomNum,email);

            if(isSuccess) {
                //设置定时缓存
                redisTemplate.boundValueOps("message.email."+email+".validcode").set(randomNum, 10, TimeUnit.MINUTES);
                resultData=new ResultData(MessageEnum.SUCCESS);
            } else {
                resultData=new ResultData(MessageEnum.MAIL_SEND_FAIL);
            }

        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }





    /**
     * 上传图片
     */
    @ResponseBody
    @RequestMapping(value = "/upload")
    @ApolloSecurity(limit = 20,time = TimeEnum.MINUTE)
    public ResultData upload (@RequestParam MultipartFile uploadFile) {
        ResultData  resultData ;
        try {
            if(uploadFile==null||uploadFile.isEmpty()){
               throw new ApolloException(MessageEnum.UPLOAD_FILE_EMPTY);
           }else if(uploadFile.getSize()> sysConfig.getFileMaxsize()){
               throw new ApolloException(MessageEnum.UPLOAD_FILE_TOOMAX);
           }

           String fileType= uploadFile.getOriginalFilename();
            fileType=fileType.substring(fileType.lastIndexOf(".")).toLowerCase();
            //文件格式校验
            if( !sysConfig.getFileType().contains(fileType.replace(".",""))){
                throw new ApolloException(MessageEnum.UPLOAD_FILE_FORMAT_EROOR);
            }

            // 七牛
//            String url=systemService.upload(uploadFile.getBytes(),fileType.toLowerCase());

            //OSS
            String url = oSSManageUtil.uploadImg(uploadFile);
            Map<String,String> map= Maps.newHashMap();
            map.put("url",url);
            resultData=new ResultData(MessageEnum.SUCCESS,map);
        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }


    /**
     * 上传多张图片
     */
    @ResponseBody
    @RequestMapping(value = "/multi/upload")
    @ApolloSecurity(limit = 20,time = TimeEnum.MINUTE)
    public ResultData upload (@RequestParam MultipartFile[] uploadFiles) {
        ResultData  resultData ;
        try {
            if(uploadFiles==null||uploadFiles.length==0){
                throw new ApolloException(MessageEnum.UPLOAD_FILE_EMPTY);
            }

            List<String> urlList = Lists.newArrayList();
            for(int i = 0;i<uploadFiles.length;i++){
                MultipartFile uploadFile = uploadFiles[i];
                String fileType= uploadFile.getOriginalFilename();
                fileType=fileType.substring(fileType.lastIndexOf(".")).toLowerCase();
                //文件格式校验
                if( !sysConfig.getFileType().contains(fileType.replace(".",""))){
                    throw new ApolloException(MessageEnum.UPLOAD_FILE_FORMAT_EROOR);
                }
                if(uploadFile.getSize()> sysConfig.getFileMaxsize()){
                    throw new ApolloException(MessageEnum.UPLOAD_FILE_TOOMAX);
                }

                String url=systemService.upload(uploadFile.getBytes(),fileType.toLowerCase());
                urlList.add(url);
            }

            Map<String,Object> map= Maps.newHashMap();
            map.put("list",urlList);
            resultData=new ResultData(MessageEnum.SUCCESS,map);
        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }


    /**
     * 上传多张图片
     */
    @ResponseBody
    @RequestMapping(value = "/qiniu/token")
    @ApolloSecurity(auth = AuthEnum.PUBLIC,limit = 20,time = TimeEnum.MINUTE)
    public ResultData getToken () {
        ResultData  resultData ;
        try {
            Map<String,Object> map = Maps.newHashMap();
            map.put("token",systemService.getToken());
            resultData=new ResultData(MessageEnum.SUCCESS,map);
        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }




    /**
     * 获取app核心配置
     */
    @ResponseBody
    @RequestMapping(value = "/properties")
    public ResultData properties (String isIOS) {
        ResultData  resultData ;
        try {
            if(isIOS==null){
                throw new ApolloException(MessageEnum.PARMA_IS_EMPTY);
            }else if( isIOS.length()!=1|| !"YN".contains(isIOS)){
                throw new ApolloException(MessageEnum.PARMA_FORMAT_ERROR);
            }

            List<Map<String, Object>> list= systemService.getAppProperties(isIOS);

            resultData=new ResultData(MessageEnum.SUCCESS,list);
        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }

    /**
     * 获取用户个人推送配置列表
     */
    @ResponseBody
    @RequestMapping(value = "/push/config/list")
    @ApolloSecurity(auth= AuthEnum.USER)
    public ResultData configlist (@GetUser User user) {
        ResultData  resultData ;
        try {

            //注意初始用户在配置表中没有数据
            List<Map<String, Integer>> list= systemService.getUserPushConflist(user.getId());



            resultData=new ResultData(MessageEnum.SUCCESS,list);
        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }



    /**
     * 修改用户个人推送配置列表
     */
    @ResponseBody
    @RequestMapping(value = "/push/config")
    @ApolloSecurity(auth= AuthEnum.USER)
    public ResultData config (@GetUser User user,String push_type,String state) {
        ResultData  resultData ;
        try {
            boolean b= systemService.modifyPushConfig(user.getId(),Integer.valueOf(push_type),
                    Integer.valueOf(state));

           if(b) resultData=new ResultData(MessageEnum.SUCCESS);
           else resultData=new ResultData(MessageEnum.FAILURE);

        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }

        return resultData;
    }


    @ResponseBody
    @RequestMapping(value = "/record/error/msg", method = { RequestMethod.POST })
    @ApolloSecurity(auth= AuthEnum.PUBLIC,limit = 20,time = TimeEnum.MINUTE)
    public void recordRequestError (String request_url, String error_msg) {
        try {
            systemService.addRequestErrorData(request_url,error_msg);
        } catch (Exception e) {
           //ignore error
        }
    }

    @ResponseBody
    @RequestMapping(value = "/wechat/jsSdkConfig")
    @ApolloSecurity(auth= AuthEnum.PUBLIC,limit = 20,time = TimeEnum.MINUTE)
    public ResultData wechatJsConfig (String url) {
        ResultData  resultData;
        try {
            //获取redis中的wechataccesstoken
            //设置缓存token wiki:http://mp.weixin.qq.com/wiki/15/54ce45d8d30b6bf6758f68d2e95bc627.html
            BoundValueOperations access_token_bvo = redisTemplate.boundValueOps("wechat.access_token");
            String access_token = "";
            if(access_token_bvo.setIfAbsent(1)) {
                String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+sysConfig.getWechatWebAppId()+"&secret="+sysConfig.getWechatWebAppSecret();
                JSONObject jsonObject = HttpUtils.doJsonGet(tokenUrl, null);
                access_token_bvo.set(jsonObject.get("access_token"),120,TimeUnit.MINUTES);//7200秒
                access_token = jsonObject.get("access_token").toString();
            }else{
                access_token = redisTemplate.boundValueOps("wechat.access_token").get().toString();
            }
            if(StringUtil.isEmpty(access_token)){
                return new ResultData(MessageEnum.FAILURE);
            }
            //设置缓存jsapi_ticket wiki:http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95
            BoundValueOperations jsapi_ticket_bvo = redisTemplate.boundValueOps("wechat.jsapi_ticket");
            String jsapi_ticket = "";
            if(jsapi_ticket_bvo.setIfAbsent(1)) {
                String jsapiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
                JSONObject jsonObject = HttpUtils.doJsonGet(jsapiUrl, null);
                jsapi_ticket_bvo.set(jsonObject.get("ticket"),120,TimeUnit.MINUTES);//7200秒
                jsapi_ticket = jsonObject.get("ticket").toString();
            }else{
                jsapi_ticket = jsapi_ticket_bvo.get().toString();
            }
            if(StringUtil.isEmpty(jsapi_ticket)){
                return new ResultData(MessageEnum.FAILURE);
            }
            Map map = wechatJsSign.sign(jsapi_ticket,url);
            map.put("appid",sysConfig.getWechatWebAppId());
            resultData=new ResultData(MessageEnum.SUCCESS,map);
//            else resultData=new ResultData(MessageEnum.FAILURE);

        }catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }
}
